# ifndef _MODELO_H_

# define _MODELO_H_

# include <iostream>

# include <list>

# include <stack>

# include "../Vista/vista.h"

# include "figura.h"

# include "punto.h"

# include "linea.h"

# include "rectangulo.h"

# include "circulo.h"

# include "poligono.h"

# include "puntoDibujo.h"

# include "grupo.h"

using namespace std;

class Vista;

enum Hist {accionCrear, accionBorrar, accionAgrupar, accionDesagrupar, accionRedimensionar, accionMover};

class Historial
{
	public:
	
		Historial():hist(accionCrear), x(0), y(0)
		{
		};
		
		Historial(Hist h, float vx = 0, float vy = 0): hist(h), x(vx), y(vy) 
		{
		};
		
		Historial(const Historial& h): figuras(h.figuras), hist(h.hist), x(h.x), y(h.y) 
		{
		};
		
		~Historial() 
		{
		};
		
		void addFigura (Figura* f) 
		{
			figuras.push_back(f);
		};
		
		void setFiguras (list<Figura*> f) 
		{
			figuras = f;
		};
		
		void setFigura (Figura* f) 
		{
			figuras.clear(); 
			
			figuras.push_back(f);
		}
		
		list<Figura*> getFiguras () const 
		{
			return (figuras);
		};
		
		void setHist (Hist h) 
		{
			hist = h;
		};
		
		Hist getHist() const 
		{
			return hist;
		};
		
		void setX(float vx) 
		{
			x = vx;
		};
		
		float getX() const 
		{
			return x;
		};
		
		void setY(float vy) 
		{
			y = vy;
		};
		
		float getY() const 
		{
			return y;
		};
		
	private:
		
		list<Figura*> figuras;
		
		Hist hist;
		
		float x;
		
		float y;
};

class Modelo
{
	friend class Vista;
  
	public:

		Modelo() 
		{
		};
		
		Modelo(const Modelo&) 
		{
		};
		
		~Modelo() 
		{
		};
		
		Modelo& operator= (const Modelo&);
		
		void actualizar_vistas(Vista* v = NULL);
		
		virtual void anyadirFigura(Figura* f, bool = false) = 0;
		
		virtual bool quitarFigura(Figura*, bool = false) = 0;
		
		virtual string Texto(int = 0) = 0;
		
		virtual void leerFichero(string) = 0;
		
		virtual list<Figura*> Pintar() = 0;
		
		virtual Figura* seleccionar (float, float) = 0;
		
		virtual list<Figura*> seleccionar (Punto, Punto) = 0;
		
		virtual Grupo* agrupar (list<Figura*>, bool = false) = 0;
		
		virtual void desagrupar (Grupo* g, bool = false) = 0;
		
		virtual void redimensionar (list<Figura*>, float, float, bool = false) = 0;
		
		virtual void trasladar (list<Figura*>, float, float, bool = false) = 0;
		
		static void normalizaPuntos (Punto&, Punto&);
		
		virtual void Deshacer() = 0;
		
		virtual void Rehacer() = 0;
		
		virtual void vaciarHistorial() = 0;
		
		virtual void vaciarDeshacer() = 0;
		
		virtual void Iniciar() = 0;		
		
	protected:
  
		list<Vista*> lv;

		void anyadir_vista(Vista* v) 
		{ 
			lv.push_back(v); 
		};
		
		list<Figura*> figuras;
		
		stack<Historial*> historial;
		
		stack<Historial*> deshacer;

	private:
};

# endif
